﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace GylCSharpUtils.Common.Base.SpecialConverter {


    public abstract class ArraySpecialConverter<T> : ASpecialConverter {


        public override Type ConfigType() {
            return typeof(T[]);
        }

        public override object ToObject(byte[] data) {
            int len = CalcDSerialDataLen(data);
            T[] result = new T[len];
            Buffer.BlockCopy(data, 4, result, 0, data.Length - 4);
            return result;
        }

        public override byte[] ToByteArray(object data) {
            T[] arr = (T[])data;
            int resultLen = CalcSerialByteArrLen(arr.Length);
            byte[] result = new byte[resultLen];
            Buffer.BlockCopy(arr, 0, result, 4, resultLen - 4);  // 将所有的数据写入数组
            Buffer.BlockCopy(new int[] {arr.Length}, 0, result, 0, 4); //将数量信息写入数组
            return result;
        }


        public int ByteNumPerValue() {
            return Marshal.SizeOf(typeof(T));
        }
        private int CalcSerialByteArrLen(int dataLen) {
            return ByteNumPerValue() * dataLen + 4;
        }
        private int CalcDSerialDataLen(byte[] data) {
            int len =  (data.Length - 4) / ByteNumPerValue();
            int[] num = new int[1];
            Buffer.BlockCopy(data, 0, num, 0, 4);
            if(num[0] != len) {
                throw new Exception($"数据长度不正确，标记数据量为{num[0]}, 实际为 {len}");
            }
            return len;
        }


    }

    public class ByteArraySpecialConverter : ArraySpecialConverter<byte> {

    }

    public class ShortArraySpecialConverter : ArraySpecialConverter<short> {

    }

    public class IntArraySpecialConverter : ArraySpecialConverter<int> {

    }
    public class LongArraySpecialConverter : ArraySpecialConverter<long> {

    }
    public class SByteArraySpecialConverter : ArraySpecialConverter<sbyte> {

    }
    public class UShortArraySpecialConverter : ArraySpecialConverter<ushort> {

    }
    public class UIntArraySpecialConverter : ArraySpecialConverter<uint> {

    }
    public class ULongArraySpecialConverter : ArraySpecialConverter<ulong> {

    }
    public class BoolArraySpecialConverter : ArraySpecialConverter<bool> {

    }
    public class FloatArraySpecialConverter : ArraySpecialConverter<float> {

    }
    public class DoubleArraySpecialConverter : ArraySpecialConverter<double> {

    }

    public class CharArraySpecialConverter : ArraySpecialConverter<char> {

    }
}
